using System;
using System.Linq.Expressions;
using NLite.Reflection;
using System.Reflection;

namespace NLite.Log
{
    [Serializable]
    sealed class NullLogger : ILog
    {
        public static readonly NullLogger Instance = new NullLogger();

        public NullLogger()
        {
        }

        public void Debug(object message)
        {
        }

        public void Debug(object message, Exception exception)
        {
        }

        public void DebugFormat(string format, params Object[] args)
        {
        }

        public bool IsDebugEnabled
        {
            get { return false; }
        }

        public void Info(object message)
        {
        }

        public void Info(object message, Exception exception)
        {
        }

        public void InfoFormat(string format, params Object[] args)
        {
        }

        public bool IsInfoEnabled
        {
            get { return false; }
        }

        public void Warn(object message)
        {
        }

        public void Warn(object message, Exception exception)
        {
        }

        public void WarnFormat(string format, params Object[] args)
        {
        }

        public bool IsWarnEnabled
        {
            get { return false; }
        }

        public void Error(object message)
        {
        }

        public void Error(object message, Exception exception)
        {
        }

        public void ErrorFormat(string format, params Object[] args)
        {
        }

        public bool IsErrorEnabled
        {
            get { return false; }
        }

        public void Fatal(object message)
        {
        }

        public void Fatal(object message, Exception exception)
        {
        }

        public void FatalFormat(string format, params Object[] args)
        {
        }

        public bool IsFatalEnabled
        {
            get { return false; }
        }

    }

    class Log4NetLogger : ILog
    {
      
        private readonly object logger;

        internal static readonly System.Type LogManagerType;
        private static readonly MethodInfo GetLoggerMethodByString;
        private static readonly MethodInfo GetLoggerMethodByType;
        static Log4NetLogger()
        {
            try
            {
                LogManagerType = System.Type.GetType("log4net.LogManager, log4net");
                if (LogManagerType == null)
                    return;

                GetLoggerMethodByString = LogManagerType.GetMethod("GetLogger", new Type[] { typeof(string) });
                GetLoggerMethodByType = LogManagerType.GetMethod("GetLogger", new Type[] { typeof(Type) });
            }
            finally
            {
            }
        }

        public Log4NetLogger(string name)
        {
            this.logger = GetLoggerMethodByString.FastFuncInvoke(null,name);
        }

        public Log4NetLogger(Type type)
        {
            this.logger = GetLoggerMethodByType.FastFuncInvoke(null, type);
        }

        public bool IsErrorEnabled
        {
            get { return logger.GetProperty<bool>("IsErrorEnabled"); }
        }

        public bool IsFatalEnabled
        {
            get { return logger.GetProperty<bool>("IsFatalEnabled"); }
        }

        public bool IsDebugEnabled
        {
            get { return logger.GetProperty<bool>("IsDebugEnabled"); }
        }

        public bool IsInfoEnabled
        {
            get { return logger.GetProperty<bool>("IsInfoEnabled"); }
        }

        public bool IsWarnEnabled
        {
            get { return logger.GetProperty<bool>("IsWarnEnabled"); }
        }

        public void Error(object message)
        {
            logger.Proc("Error", message);
        }

        public void Error(object message, Exception exception)
        {
            logger.Proc("Error", message,exception);
        }

        public void ErrorFormat(string format, params object[] args)
        {
            logger.Proc("ErrorFormat", format, args);
        }

        public void Fatal(object message)
        {
            logger.Proc("Fatal", message);
        }

        public void Fatal(object message, Exception exception)
        {
            logger.Proc("Fatal", message, exception);
        }

        public void Debug(object message)
        {
            logger.Proc("Debug", message);
        }

        public void Debug(object message, Exception exception)
        {
            logger.Proc("Debug", message, exception);
        }

        public void DebugFormat(string format, params object[] args)
        {
            logger.Proc("DebugFormat", format, args);
        }

        public void Info(object message)
        {
            logger.Proc("Info", message);
        }

        public void Info(object message, Exception exception)
        {
            logger.Proc("Info", message, exception);
        }

        public void InfoFormat(string format, params object[] args)
        {
            logger.Proc("InfoFormat", format, args);
        }

        public void Warn(object message)
        {
            logger.Proc("Warn", message);
        }

        public void Warn(object message, Exception exception)
        {
            logger.Proc("Warn", message, exception);
        }

        public void WarnFormat(string format, params object[] args)
        {
            logger.Proc("WarnFormat", format, args);
        }
    }
}
